﻿using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Collections;
namespace ConsolidationTool.LeftNavigation.CONTROLTEMPLATES
{
    public partial class LeftNaviation : UserControl
    {
        const string TopNavListName = "Left Navigation";
        bool isExpand = false;
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                if (HttpContext.Current.Cache["Navigation"] == null)
                    HttpContext.Current.Cache["Navigation"] = GetDataSourceXml();
                // Assigns XML string to the XMLDataSource object
                XmlDataSourceTopNavigation.Data = HttpContext.Current.Cache["Navigation"].ToString();
                // Sets datasource property for the Menu control
                TreeNodeBinding cnb = new TreeNodeBinding();
                cnb.DataMember = "menuItem";
                cnb.TextField = "title";
                cnb.NavigateUrlField = "url";
                TV.DataBindings.Add(cnb);
                // Binds the data to the control
                TV.DataSourceID = XmlDataSourceTopNavigation.ID;
                TV.DataBind();
                //Restore TreeViewStatus
                RestoreTV(TV);

                BindTreeView(null);
            }
        }
        private string GetDataSourceXml()
        {
            //   const string menuItemTemplate = "<menuItem url=\"{0}\" title=\"{1}\" />";
            const string menuFirstSetionTemplate = "<menuItem url=\"{0}\" title=\"{1}\">";
            const string menuSecondSetionTemplate = "</menuItem>";

            var xmlData = new StringBuilder();
            xmlData.AppendLine("<?xml version=\"1.0\" encoding=\"utf-8\" ?>");
            xmlData.AppendLine("<menu>");

            try
            {
                SPWeb web = SPContext.Current.Web;
                SPList list = web.Lists.TryGetList(TopNavListName);
                if (list != null)
                {
                    const string queryStr = @"<OrderBy><FieldRef Name='ConsolidationTool_ParentId' /><FieldRef Name='ConsolidationTool_Sequence' /></OrderBy>";
                    SPQuery query = new SPQuery();
                    query.Query = queryStr;
                    query.RowLimit = 2000;

                    SPListItemCollection items = list.GetItems(query);
                    List<Menu> menuList = new List<Menu>();
                    foreach (SPListItem item in items)
                    {
                        Menu m = new Menu();
                        m.MenuId = int.Parse(item["ConsolidationTool_MenuId"].ToString());
                        m.ParentId = int.Parse(item["ConsolidationTool_ParentId"].ToString());
                        m.Sequence = int.Parse(item["ConsolidationTool_Sequence"].ToString());
                        m.Title = item["Title"].ToString();
                        m.Url = item["ConsolidationTool_Url"].ToString();
                        menuList.Add(m);
                    }
                    Cache["fs_navigation"] = menuList;

                    GetMenu(menuList, xmlData, menuFirstSetionTemplate, menuSecondSetionTemplate);
                }
            }
            catch (Exception ex)
            {

            }
            xmlData.AppendLine("</menu>");
            return xmlData.ToString().Replace("&", "&amp;");
        }
        private void BindTreeView(List<Menu> list)
        {
            tvNavigation.Nodes.Clear();

            if (list == null)
                list = Cache["fs_navigation"] as List<Menu>;
            bool withSelected = false;

            list.FindAll(p => p.ParentId == 0).ForEach(p =>
            {
                var rootNode = new TreeNode();
                rootNode.Text = p.Title;
               // rootNode.NavigateUrl = "#";
                rootNode.Value = p.MenuId + "";
                rootNode.SelectAction = TreeNodeSelectAction.Expand;

                list.FindAll(a => a.ParentId == p.MenuId).ForEach(c =>
                {
                    var secnode = new TreeNode()
                    {
                        Text = c.Title,
                        SelectAction = TreeNodeSelectAction.Expand,
                    //    NavigateUrl = "#",
                        Value = c.MenuId + ""
                    };

                    list.FindAll(d => d.ParentId == c.MenuId).ForEach(e =>
                    {

                        var endNode = new TreeNode()
                        {

                            Text = e.Title,
                            SelectAction = TreeNodeSelectAction.Select,
                            NavigateUrl = e.Url,
                            Value = e.MenuId + ""
                        };

                        if (!withSelected && Request.RawUrl.EndsWith(e.Url))
                        {
                            withSelected = true;
                            endNode.Text = string.Format("<span class=\"fs_nav_selected\">{0}</span>", endNode.Text);
                            endNode.Selected = true;
                        }
                        secnode.ChildNodes.Add(endNode);
                    });

                    rootNode.ChildNodes.Add(secnode);
                });

                tvNavigation.Nodes.Add(rootNode);
            });

            tvNavigation.CollapseAll();
            ChangeSelectedStyle(tvNavigation.Nodes);
        }

        private void ChangeSelectedStyle(TreeNodeCollection treeNodeCollection)
        {
            foreach (TreeNode item in treeNodeCollection)
            {
                if (item.ChildNodes.Count > 0)
                    ChangeSelectedStyle(item.ChildNodes);
                else
                {
                    if (item.Selected)
                    {
                        ExpandToCurrentNode(item);
                    }
                }
            }
        }

        private void ExpandToCurrentNode(TreeNode item)
        {
            item.Expand();
            if (item.Parent != null)
                ExpandToCurrentNode(item.Parent);
        }


        private void GetMenu(List<Menu> list, StringBuilder xmlData, string NodeStart, string NodeEnd)
        {


            List<Menu> rootList = list.FindAll(m => m.ParentId == 0);
            foreach (Menu m in rootList)
            {
                xmlData.AppendLine(string.Format(NodeStart, m.Url, m.Title));
                bindSubMenu(m, list, xmlData, NodeStart, NodeEnd);
                xmlData.AppendLine(NodeEnd);
            }
        }
        private void bindSubMenu(Menu m, List<Menu> list, StringBuilder xmlData, string NodeStart, string NodeEnd)
        {
            List<Menu> subList = list.FindAll(sm => sm.ParentId == m.MenuId);
            foreach (Menu sm in subList)
            {
                xmlData.AppendLine(string.Format(NodeStart, sm.Url, sm.Title));
                bindSubMenu(sm, list, xmlData, NodeStart, NodeEnd);
                xmlData.AppendLine(NodeEnd);
            }
        }

        protected void TV_TreeNodeExpanded(object sender, TreeNodeEventArgs e)
        {
            if (!isExpand)
                SaveTV(TV);
        }

        protected void TV_TreeNodeCollapsed(object sender, TreeNodeEventArgs e)
        {
            SaveTV(TV);
        }
        void RestoreTV(TreeView tv)
        {
            if (HttpContext.Current.Request.Cookies["TvStatus"] != null)
            {
                string[] list = HttpContext.Current.Request.Cookies["TvStatus"].Value.Split('|');
                RestoreTVCollapseStatus(tv.Nodes, list);
            }
        }
        void SaveTV(TreeView tv)
        {
            ArrayList list = new ArrayList();
            SaveTVExpandStatus(tv.Nodes, list);
            HttpCookie cookie = new HttpCookie("TvStatus");
            cookie.Value = string.Join("|", ArrList2String(list));
            HttpContext.Current.Response.Cookies.Add(cookie);
        }
        void SaveTV(TreeView tv, ArrayList aList)
        {
            SaveTVExpandStatus(tv.Nodes, aList);
            HttpCookie cookie = new HttpCookie("TvStatus");
            cookie.Value = string.Join("|", ArrList2String(aList));
            HttpContext.Current.Response.Cookies.Add(cookie);
        }
        void RestoreTVCollapseStatus(TreeNodeCollection nodes, string[] list)
        {
            ArrayList aList = new ArrayList(list);
            foreach (TreeNode node in nodes)
            {
                string key = string.Empty;
                if (node.Parent != null)
                    key = node.Parent.Text + "-" + node.Text;
                else
                    key = node.Text;

                foreach (string sNode in aList)
                {
                    if (key.Equals(sNode))
                    {
                        isExpand = true;
                        node.Expanded = true;
                        break;
                    }
                }
                if (node.ChildNodes.Count > 0)
                    RestoreTVCollapseStatus(node.ChildNodes, list);
            }
            isExpand = false;
            SaveTV(TV, aList);
        }
        void SaveTVExpandStatus(TreeNodeCollection nodes, ArrayList list)
        {
            foreach (TreeNode node in nodes)
            {
                if (node.Expanded != null && (bool)node.Expanded)
                {
                    if (node.Parent != null)
                        list.Add(node.Parent.Text + "-" + node.Text);
                    else
                        list.Add(node.Text);
                }
                if (node.ChildNodes.Count > 0)
                    SaveTVExpandStatus(node.ChildNodes, list);
            }
        }
        string[] ArrList2String(ArrayList list)
        {
            return (string[])list.ToArray(typeof(string));
        }

        protected void TV_SelectedNodeChanged(object sender, EventArgs e)
        {
            var selected = TV.SelectedNode;
        }

        protected void tvNavigation_SelectedNodeChanged(object sender, EventArgs e)
        {

        }
    }
    [Serializable]
    public class Menu
    {
        public int MenuId { get; set; }
        public int ParentId { get; set; }
        public int Sequence { get; set; }
        public string Title { get; set; }
        public string Url { get; set; }
    }
}
